using System;
using System.Collections.Generic;
using System.Text;
using Calc.Execution;

namespace Calc.Operations
{
	public class Function : Variable
	{
		protected List<IOperand> _variables;
		protected IOperand _operation;

		public Function()
			: this("")
		{

		}

		public Function(string name)
			: this(name, null, null)
		{

		}


		public Function(string name, List<IOperand> variables, IOperand operation)
			: base(name)
		{
			if ( variables != null )
				_variables = variables;
			else
				_variables = new List<IOperand>(1);	// should always have at least one variable

			_operation = operation;
		}

		public Function(Variable variable)
			: this(( variable == null ? "" : variable.Name ), null, null)
		{
		}


		public List<IOperand> Variables
		{
			get { return _variables; }
		}

		public IOperand Operation
		{
			get { return _operation; }
			set { _operation = value; }
		}

		public override double GetValue(ExecutionContext context)
		{
			if ( _operation == null )
				throw new ArgumentNullException("Operation", "Operation can not be null");

			double value = _operation.GetValue(context);

			return value;
		}

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();

			sb.Append(_name).Append("(");

			bool first = true;
			foreach ( IOperand op in _variables )
			{
				if ( first )
					first = false;
				else
					sb.Append(",");

				sb.Append(op.ToString());
			}

			sb.Append(")");
			return sb.ToString();
		}
	}
}
